<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Baidu Map</title>
    <style type="text/css">
      html {
        height: 100%;
      }
      body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #container {
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="container"></div>

    <!-- 只加载一次百度地图 WebGL API -->
    <script
      type="text/javascript"
      src="//api.map.baidu.com/api?v=2.0&ak=sENPTAUGJcXwOMi9TEBEH7kRM0yk623Q"
    ></script>
    <script
      type="text/javascript"
      src="https://api.map.baidu.com/api?v=2.0&type=webgl&ak=sENPTAUGJcXwOMi9TEBEH7kRM0yk623Q"
    ></script>
    <script src="https://api.map.baidu.com/api?v=3.0&ak=sENPTAUGJcXwOMi9TEBEH7kRM0yk623Q"></script>
    <script>
      let place = {
        latitude: 25.818247,
        longitude: 114.920426,
        user_latitude: 25.819178,
        user_longitude: 114.964335,
        model: 1, // 默认查看位置页
      }

      let map
      let carPoint // 纠偏后的车辆坐标（BD09）
      let userPoint // 纠偏后的用户坐标（BD09）

      // 监听应用侧事件
      window.addEventListener('message', function (event) {
        if (event.data === '__init_port__') {
          if (event.ports[0] !== null) {
            h5Port = event.ports[0] // 1. 保存从应用侧发送过来的端口。
            h5Port.onmessage = function (event) {
              h5Port.onmessage = async function (event) {
                // 2. 接收ets侧发送过来的消息
                var msg = ''
                var result = event.data
                if (typeof result === 'string') {
                  console.info(
                    `received string message from html5, string is: ${result}`
                  )
                  msg = msg + result
                } else if (typeof result === 'object') {
                  if (result instanceof ArrayBuffer) {
                    console.info(
                      `received arraybuffer from html5, length is: ${result.byteLength}`
                    )
                    msg = msg + 'length is ' + result.byteLength
                  }
                }
                place = JSON.parse(msg)
                initMap()
              }
            }
          }
        }
      })

      // 初始化地图
      function initMap() {
        map = new BMapGL.Map('container')
        map.enableScrollWheelZoom()

        // 坐标转换（WGS84 -> BD09）
        const convertor = new BMap.Convertor()

        // 转换车辆坐标
        convertor.translate(
          [new BMap.Point(place.longitude, place.latitude)],
          1, // WGS84
          5, // BD09
          (data) => {
            if (data.status === 0 && data.points.length > 0) {
              carPoint = data.points[0]
              map.centerAndZoom(carPoint, 15)
              addCarMarker(carPoint)
            }
          }
        )

        // 转换用户坐标
        convertor.translate(
          [new BMap.Point(place.user_longitude, place.user_latitude)],
          1,
          5,
          (data) => {
            if (data.status === 0 && data.points.length > 0) {
              userPoint = data.points[0]
              addUserMarker(userPoint)
            }
          }
        )

        setTimeout(searchChargingStations, 500)
      }

      // 添加车辆标记
      function addCarMarker(point) {
        const carIcon = new BMapGL.Icon(
          'https://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png',

          new BMapGL.Size(25, 28)
        )
        const marker = new BMapGL.Marker(point, { icon: carIcon })
        map.addOverlay(marker)
      }

      // 添加用户标记
      function addUserMarker(point) {
        const userIcon = new BMapGL.Icon(
          'https://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',

          new BMapGL.Size(25, 28)
        )
        const marker = new BMapGL.Marker(point, { icon: userIcon })
        map.addOverlay(marker)
      }

      // 充电桩查询（使用纠偏后的车辆坐标）
      function searchChargingStations() {
        if (!carPoint) return

        // 高德地图 API（需转换为 WGS84 坐标）
        fetch(
          `https://restapi.amap.com/v3/place/around?key=4dca16b51c8a82dab8f426bb850317e8&location=${
            carPoint.lng - 0.006
          },${carPoint.lat - 0.006}&radius=10000&types=011100`
        )
          .then((response) => response.json())
          .then((data) => {
            data.pois.forEach((poi) => {
              // 高德返回的是 GCJ02 坐标，需再次转换为 BD09
              const convertor = new BMap.Convertor()
              convertor.translate(
                [
                  new BMap.Point(
                    poi.location.split(',')[0],
                    poi.location.split(',')[1]
                  ),
                ],
                3, // GCJ02
                5, // BD09
                (data) => {
                  if (data.status === 0 && data.points.length > 0) {
                    const stationPoint = data.points[0]
                    addChargingStationMarker(stationPoint, poi)
                  }
                }
              )
            })
          })
      }

      // 添加充电桩标记
      function addChargingStationMarker(point, poi) {
        const icon = new BMapGL.Icon(
          'https://webapi.amap.com/images/mass/mass1.png',
          new BMapGL.Size(18, 18)
        )
        const marker = new BMapGL.Marker(point, { icon })

        // 创建信息窗口内容
        var infoContent = poi.photos?.[0]?.url
          ? `
      <div class="info-window" style="overflow: visible">
        <h3>${poi.name}</h3>
        <p>地址: ${poi.address}</p>
        <p>距离: ${(poi.distance / 1000).toFixed(1)}公里</p>
        <img src="${
          poi.photos[0].url
        }" alt="充电桩图片" style="width: 100%; height: auto;"/>
      </div>
    `
          : `
      <div class="info-window">
        <h3>${poi.name}</h3>
        <p>地址: ${poi.address}</p>
        <p>距离: ${(poi.distance / 1000).toFixed(1)}公里</p>
      </div>
    `
        const infoWindow = new BMapGL.InfoWindow(infoContent, {
          width: 200,
          height: 150,
          title: '充电桩信息',
        })

        marker.addEventListener('click', () => {
          map.openInfoWindow(infoWindow, point)
        })
        map.addOverlay(marker)
      }
    </script>
  </body>
</html>
